<template>
    <div>
        <scroll class="listview" @scroll="scroll" :data="data" :listen-scroll="listenScroll" :probeType="probeType" ref="listview">
            <!--中央滚动区-->
            <ul>
                <!--顶部插槽-->
                <div ref="slotKey"><slot></slot></div>

                <li v-for="(group, index) in data" class="list-group" :key="index" ref="listGroup">
                    <div class="list-group-title">{{ group.title }}</div>
                    <ul>
                        <li @click="selectItem(item)" v-for="(item, index) in group.items" :key="index" class="list-group-item">
                            <span class="name">{{ item.name }}</span>
                        </li>
                    </ul>
                </li>
            </ul>
        </scroll>
        <!--快速选择区-->
        <div class="list-shortcut" @touchstart="onShortcutStart" @touchmove.stop.prevent="onShortcutMove">
            <ul>
                <li v-for="(item, index) in shortcutList" class="item" :data-key="index" :key="index" :class="{current: currentIndex === index}">
                    {{ item }}
                </li>
            </ul>
        </div>

        <!--loading-->
        <!--<div v-show="!data.length" class="loading-container"><van-loading /></div>-->
        <!--固定title-->
        <div class="list-fixed" v-show="fixedTitle" ref="fixed">
            <h1 class="fixed-title">{{ fixedTitle }}</h1>
        </div>
    </div>
</template>

<script>
import Scroll from 'common/scroll';

const ANCHOR_HEIGHT = 18; //快速选择区的项高(font14+pading3*2=18)
const TITLE_HEIGHT = 30; //组title的行高

export default {
    data() {
        return {
            scrollY: -1, //当前滚动的纵向位置
            currentIndex: 0, //当前滚动位置的组项索引
            diff: -1 //区域顶部至当前滚动项下限的高度差
        };
    },
    created() {
        this.touch = {};
        this.listenScroll = true;
        this.listHeight = [];
        this.probeType = 3;
    },
    mounted() {
        this._calculateHeight()
    },
    props: {
        data: {
            type: Array,
            default: function() {
                return [];
            }
        }
    },
    components: {
        Scroll
    },
    computed: {
        shortcutList: function() {
            return this.data.map((group) => {
                return group.title.substr(0, 1);
            });
        },
        fixedTitle() {
            if (this.currentIndex <= 0) {
                return '';
            }
            return this.data[this.currentIndex] ? this.data[this.currentIndex].title : '';
        },
    },
    methods: {
        selectItem(item) {
            this.$emit('select', item);
        },
        onShortcutStart: function(e) {
            let anchorindex = parseInt(e.target.getAttribute('data-key'));
            let firstTouch = e.touches[0];
            this.touch.y1 = firstTouch.pageY;
            this.touch.anchorIndex = anchorindex;
            this._scrollTo(anchorindex);
        },
        onShortcutMove: function(e) {
            let firstTouch = e.touches[0];
            this.touch.y2 = firstTouch.pageY;
            let delta = ((this.touch.y2 - this.touch.y1) / ANCHOR_HEIGHT) | 0;
            let anchorIndex = this.touch.anchorIndex + delta;
            this._scrollTo(anchorIndex);
        },
        //实时滚动 监听滚动位置
        scroll(pos) {
            this.scrollY = pos.y;
        },
        refresh() {
            this.$refs.listview.refresh();
        },
        _scrollTo(index) {
            if (isNaN(index)) {
                return;
            } else if (index < 0) {
                index = 0;
            } else if (index > this.listHeight.length - 2) {
                index = this.listHeight.length - 2;
            }
            this.currentIndex = index;
            this.$refs.listview.scrollToElement(this.$refs.listGroup[index], 0);
        },
        //计算每组group上下限高度,存入listHeight,首项上限为0+slotHeight
        _calculateHeight() {
            //插槽区高度
            const slotHeight = this.$refs.slotKey.clientHeight;
            this.listHeight = [];
            const list = this.$refs.listGroup;
            let height = 0;
            this.listHeight.push(height);
            for (let i = 0; i < list.length; i++) {
                height += list[i].clientHeight;
                this.listHeight.push(height + slotHeight);
            }
        }
    },
    watch: {
        //data变化 重新计算每组height
        data() {
            setTimeout(() => {
                this._calculateHeight();
            }, 20);
        },
        //scrollY变化 重新计算当前项currentIndex
        scrollY(newY) {
            const listHeight = this.listHeight;
            // 当滚动到底部newY>0
            if (newY >= 0) {
                this.currentIndex = 0;
                return;
            }
            // 在中间部分滚动
            for (let i = 0; i < listHeight.length - 1; i++) {
                let height1 = listHeight[i];
                let height2 = listHeight[i + 1];
                if (-newY >= height1 && -newY < height2) {
                    this.currentIndex = i;
                    this.diff = height2 + newY;
                    return;
                }
            }
            // 当滚动到底部，且-newY > 最后一个元素的上限
            this.currentIndex = listHeight.length - 2;
        },
        //区域顶部至当前滚动项下限的高度差 变化时更改fixtitle的位置(只在diff<TITLE_HEIGHT时起作用)
        diff(newVal) {
            let fixedTop = newVal > 0 && newVal < TITLE_HEIGHT ? newVal - TITLE_HEIGHT : 0;
            if (this.fixedTop === fixedTop) {
                return;
            }
            this.fixedTop = fixedTop;
            this.$refs.fixed.style.transform = `translate3d(0,${fixedTop}px,0)`;
        }
    }
};
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
@import '~assets/main.styl'

.listview {
    position: relative
    width: 100vw
    height 100vh
    overflow: hidden
    background grayF
    .list-group {
        .list-group-title {
            position sticky
            top 0
            height: vw(30)
            line-height: vw(30)
            padding-left: vw(20)
            font-size: word14
            color: gray3
            background: grayE
            margin: 0
        }
        .list-group-item {
            display: flex
            align-items: center
            padding: vw(10) 0 vw(10) vw(20)
            border-bottom vw(0.5) solid rgba(0, 0, 0, 0.15)
            .name {
                color: gray3
                font-size: word16
            }
        }
    }
}

.list-shortcut {
    position: fixed
    z-index: 30
    right: 0
    top: 50%
    transform: translateY(-50%)
    width: vw(20)
    padding: vw(20) 0
    border-radius: vw(10)
    text-align: center
    background: rgba(0, 0, 0, 0.3)
    .item {
        padding: vw(3)
        line-height: 1.4
        color: gray3
        font-size: vw(7)
        &.current {
            color: main-color
        }
    }
}

.list-fixed {
    position: absolute
    top: 0
    left: 0
    width: 100%
    .fixed-title {
        height: vw(30)
        line-height: vw(30)
        padding-left: vw(20)
        font-size: word14
        color: gray3
        background: grayE
        margin: 0
    }
}

.loading-container {
    position: absolute
    top: 50%
    left: 50%
    transform: translate(-50%, -50%)
}
</style>
